var fs = require('fs'), 
http = require('http'), 
socketio = require('socket.io'),
mongoose = require('mongoose'), 
path = require("path"),  
url = require("url"),
express = require('express'),
cookie = require('cookie'),
connect = require('connect'),
doT = require('express-dot');

process.on('uncaughtException', function (err) {
	console.log(err);
});

//basic config
var config = require('./config.json');
delete require.cache[require.resolve('./config.json')];

//basic file server and page parsing
var app = express();
app.configure(function () {
    app.use(express.cookieParser());
    app.use(express.session({secret: 'secret', key: 'express.sid'}));
	
	// should be placed before express.static
	app.use(express.compress({
		filter: function (req, res) {
		  return /json|text|javascript|css/.test(res.getHeader('Content-Type'))
		},
		level: 9
	}));
	app.use(express.favicon());
	
	app.set('views', __dirname+'/views');
	app.set('view engine', 'dot');
	app.engine('html', doT.__express);	
	app.use('/Styles',express.static(__dirname+'/views/Styles'));	
});

//dynamic pages
app.get('/', function(req, res){
	var templateData = { title: 'Thijs' };
	res.render('index.html', templateData);
});

app.get('/Main', function(req, res){
	var templateData = { title: 'Frank' };
	res.render('main.html', templateData);
});

//create sockets and handle session data
server = http.createServer(app);
server.listen(config.connection.port, function() {
	console.log('Listening at: http://localhost:' + config.connection.port);
});

var io = socketio.listen(server);
io.set('authorization', function (handshakeData, accept) {
	if (handshakeData.headers.cookie) {
		handshakeData.cookie = cookie.parse(handshakeData.headers.cookie);
		handshakeData.sessionID = connect.utils.parseSignedCookie(handshakeData.cookie['express.sid'], 'secret');
		if (handshakeData.cookie['express.sid'] == handshakeData.sessionID) {		
		  return accept('Cookie is invalid.', false);
		}
	} else {
		return accept('No cookie transmitted.', false);
	} 
	accept(null, true);
});

// Bootstrap db connection
mongoose.connect('mongodb://localhost/' + config.connection.table);

// Bootstrap models
var models_path = __dirname + '/models'
fs.readdirSync(models_path).forEach(function (file) {
	if (~file.indexOf('.js')) require(models_path + '/' + file)
})

mongoose.connection.on('error', console.error.bind(console, 'connection error:'));
var UserModel = mongoose.model('User');
var CharModel = mongoose.model('Character');

UserModel.findOne({ username: "unnown" }).exec(function(err, user) {
	console.log(user.authenticate("az61tl"));
});

//socket data handling
io.on('connection', function (socket) {
	io.enable('browser client minification');
	io.enable('browser client etag');
	io.enable('browser client gzip');
	io.set('log level', 2);	
	
	socket.on('login', function (data) {					
		UserModel.findOne({ username: data.username, banned: false }).exec(function(err, user) {
			if (!err && user != undefined && user.authenticate(data.password)) {	
				var hs = socket.handshake;
				var sessionID = hs.cookie.sessionID;
				if (typeof(sessionID) == 'undefined') sessionID = hs.sessionID;
				
				user.socketID = sessionID;
				user.isOnline = true;
				user.save();
			
				io.log.info(user.username + ' logged in');
				socket.emit('loginsucces', user);
			} else {
				io.log.warn('login failed: ' + data.username);
				socket.emit('loginfailed');
			}
		});
	});	
	
	socket.on('checklogin', function () {	
		var hs = socket.handshake;
		var sessionID = hs.cookie.sessionID;
		if (typeof(sessionID) == 'undefined') sessionID = hs.sessionID;
		
		UserModel.findOne({ socketID: sessionID, banned: false }).exec(function(err, user) {
			if (!err && user != undefined) {	
				socket.emit('loginsucces', user);
			} else {
				io.log.warn('login failed: ' + sessionID + ' (possible session manipulation)');
				socket.emit('loginfailed');
			}
		});
	});	
});